﻿using System;
using System.Windows.Controls;

namespace BitsOfStuff.MyActions
{
    /// <summary>
    /// Action , that represents generic action
    /// </summary>
    [Serializable]

    public abstract class MyAction : IComparable, IEquatable<MyAction>, ICloneable
    {
        /// <summary>
        /// Function that return action , that have hight prioruty, for example showAction>all
        /// </summary>
        /// <param name="actionA">First action to compare</param>
        /// <param name="actionB">Second action to compare</param>
        /// <returns>Action whit high prioruty</returns>
        public static MyAction getHighPriorityAction(MyAction actionA, MyAction actionB)
        {
            if (actionA.CompareTo(actionB) > -1)
                return actionA;
            return actionB;
        }

        private bool _final;

        /// <summary>
        /// Return if action is final
        /// </summary>
        /// <returns>Status of final action</returns>
        public bool isFinal()
        {
            return _final;
        }

        /// <summary>
        /// Function that set this actions as final
        /// </summary>
        public void setFinal()
        {
            _final = true;
        }

        protected MyAction()
        {
            _final = false;
        }

        protected MyAction(int priority)
        {
            setPriority(priority);
            _final = false;
        }

        /// <summary>
        /// Function for geting , if action is doing something
        /// </summary>
        /// <returns>Status of action</returns>
        public virtual bool isDoingSomething()
        {
            if (_priority > 0)
                return true;
            return false;
        }

        private int _priority;

        /// <summary>
        /// Legasy action for making action of char , now we use Events
        /// </summary>
        /// <returns>status , if action was made</returns>
        public virtual bool makeAction()
        {
            return false;
        }

        /// <summary>
        /// Function for geting int priority of action
        /// </summary>
        /// <returns>action priority</returns>
        public int getPriority()
        {
            return _priority;
        }

        private void setPriority(int priority)
        {
            _priority = priority;
        }

        /// <summary>
        /// Function for alocate local resources of InkCanvas
        /// </summary>
        /// <param name="inkCanvas">local object of inkCanvas</param>
        public virtual void assignInkCanvas(InkCanvas inkCanvas)
        { }

        /// <summary>
        /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object.
        /// </summary>
        /// <returns>
        /// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance precedes <paramref name="obj"/> in the sort order. Zero This instance occurs in the same position in the sort order as <paramref name="obj"/>. Greater than zero This instance follows <paramref name="obj"/> in the sort order.
        /// </returns>
        /// <param name="obj">An object to compare with this instance. </param><exception cref="T:System.ArgumentException"><paramref name="obj"/> is not the same type as this instance. </exception><filterpriority>2</filterpriority>
        public virtual int CompareTo(object obj)
        {
            if (obj == null) return 1;
            var myOtherAction = obj as MyAction;
            if (myOtherAction != null) return _priority.CompareTo(myOtherAction.getPriority());
            return -1;
            //throw new ArgumentException("Object is not Action");
        }

        /// <summary>
        /// Function for comparing two actions
        /// </summary>
        /// <param name="obj">Action for comparing</param>
        /// <returns>result of comparing</returns>
        public virtual int CompareTo(MyAction obj)
        {
            return 1;
        }

        /// <summary>
        /// Function for comparing this actions to List of actions
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public virtual int CompareTo(System.Collections.Generic.List<MyAction> obj)
        {
            return 1;
        }

        /// <summary>
        /// Function for determining equality
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public virtual bool Equals(MyShowAction other)
        {
            if (this == other)
                return true;
            return false;
        }

        /// <summary>
        /// Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        /// <filterpriority>2</filterpriority>
        public object Clone()
        {
            return MemberwiseClone();
        }

        /// <summary>
        /// Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <returns>
        /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
        /// </returns>
        /// <param name="other">An object to compare with this object.</param>
        public virtual bool Equals(MyAction other)
        {
            if (this is MyShowAction && other is MyShowAction)
            {
                return ((MyShowAction)this).getChar() == ((MyShowAction)other).getChar();
            }
            return CompareTo(other) == 0;
        }
    }
}